package cn.wolfcode.luowowo.search.service.impl;

import cn.wolfcode.luowowo.search.query.IndexSearchQuery;
import cn.wolfcode.luowowo.search.service.SearchQueryService;
import com.alibaba.dubbo.config.annotation.Service;
import com.alibaba.fastjson.JSON;
import org.apache.commons.beanutils.BeanUtils;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightField;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Pageable;
import org.springframework.data.elasticsearch.core.ElasticsearchTemplate;
import org.springframework.data.elasticsearch.core.SearchResultMapper;
import org.springframework.data.elasticsearch.core.aggregation.AggregatedPage;
import org.springframework.data.elasticsearch.core.aggregation.impl.AggregatedPageImpl;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;

import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;

/**
 * @author 猫教授
 * @date 2019/8/18 21:45
 */
@Service
public class SearchQueryServiceImpl implements SearchQueryService {
    @Autowired
    private ElasticsearchTemplate template;
    public <T> AggregatedPage<T> selectByKeyword(IndexSearchQuery qo, String preTag, String postTag, Class<T> clz, String Indices, String Types, String...fieldName) {
        NativeSearchQueryBuilder builder=new NativeSearchQueryBuilder();
        builder.withIndices(Indices);
        builder.withTypes(Types);
        builder.withQuery(QueryBuilders.multiMatchQuery(qo.getKeyword(),fieldName));
        builder.withPageable(qo.getPageableWithoutSort());
        HighlightBuilder.Field[] fields=new HighlightBuilder.Field[fieldName.length];
        for (int i = 0; i < fields.length; i++) {
            fields[i]=new HighlightBuilder.Field(fieldName[i]).preTags(preTag).postTags(postTag);
        }
        builder.withHighlightFields(fields);
        AggregatedPage<T> templates = template.queryForPage(builder.build(),clz, new SearchResultMapper() {
            @Override
            public <T> AggregatedPage<T> mapResults(SearchResponse response, Class<T> Class, Pageable pageable) {
                SearchHit[] hits = response.getHits().getHits();
                List<T> users = new ArrayList<>();
                for (SearchHit hit : hits) {
                    String beanStr = hit.getSourceAsString();
                    T bean = JSON.parseObject(beanStr, Class);
                    Map<String, HighlightField> highlightFields = hit.getHighlightFields();
                    Collection<HighlightField> values = highlightFields.values();
                    for (HighlightField value : values) {
                        String text = value.getFragments()[0].toString();
                        try {
                            BeanUtils.setProperty(bean, value.getName(), text);
                        } catch (IllegalAccessException e) {
                            e.printStackTrace();
                        } catch (InvocationTargetException e) {
                            e.printStackTrace();
                        }
                    }
                    users.add(bean);
                    System.out.println(users);
                }
                return new AggregatedPageImpl<T>(users, qo.getPageableWithoutSort(), response.getHits().getTotalHits());
            }
        });
        return templates;
    }
    //这三种别从从下到上是以此的封装关系






}
